package com.xmhmyh.generalframework.project.sys.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xmhmyh.generalframework.common.BaseController;
import com.xmhmyh.generalframework.common.conversion.Bean2SelectConverter;
import com.xmhmyh.generalframework.common.entity.Condition;
import com.xmhmyh.generalframework.common.entity.DataGridRequest;
import com.xmhmyh.generalframework.common.entity.Response;
import com.xmhmyh.generalframework.common.enums.*;
import com.xmhmyh.generalframework.common.utils.MyListUtils;
import com.xmhmyh.generalframework.common.vo.SelectVO;
import com.xmhmyh.generalframework.framework.aspectj.annotation.Log;
import com.xmhmyh.generalframework.framework.security.LoginUser;
import com.xmhmyh.generalframework.framework.security.TokenService;
import com.xmhmyh.generalframework.project.sys.conversion.User2UserVOConversion;
import com.xmhmyh.generalframework.project.sys.dto.LoginDTO;
import com.xmhmyh.generalframework.project.sys.dto.UserDTO;
import com.xmhmyh.generalframework.project.sys.entity.Menu;
import com.xmhmyh.generalframework.project.sys.entity.Role;
import com.xmhmyh.generalframework.project.sys.entity.User;
import com.xmhmyh.generalframework.project.sys.enums.MenuType;
import com.xmhmyh.generalframework.project.sys.service.IMenuService;
import com.xmhmyh.generalframework.project.sys.service.IRoleService;
import com.xmhmyh.generalframework.project.sys.service.IUserService;
import com.xmhmyh.generalframework.project.sys.vo.*;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author: 于丁
 * @DateTime: 2020/7/21 4:02 下午
 */
@Slf4j
@Api(tags = "用户相关接口")
@RestController
@RequestMapping("/sys/user")
public class UserController extends BaseController {
    @Autowired
    private IRoleService roleService;
    @Autowired
    private IUserService userService;
    @Autowired
    private IMenuService menuService;
    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private TokenService tokenService;

    @ApiOperation("登录接口")
    @ApiResponses({
            @ApiResponse(code = 200, message = "返回信息", response = LoginResultVO.class)
    })
    @PostMapping("login")
    public Response loginHandler(@RequestBody LoginDTO LoginDTO) {
        Authentication authentication = null;
        try {
            authentication = authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken(LoginDTO.getUsername(), LoginDTO.getPassword()));
        } catch (Exception e) {
            if (e instanceof BadCredentialsException) {
                return Response.fail(ResponseCode.USERNAME_OR_PASSWORD_ERROR);
            } else {
                return Response.fail(e.getMessage());
            }
        }
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        String token = tokenService.creatToken(loginUser);
        LoginResultVO loginResultVO = new LoginResultVO(token,loginUser.getUser().getName(),loginUser.getUser().getAccountId(),loginUser.getUser().getId());
        return Response.success(loginResultVO);
    }

    @ApiOperation("获取菜单列表数据")
    @ApiResponses({
            @ApiResponse(code = 200, message = "菜单列表数据", response = SearchMenuResultVO.class)
    })
    @PostMapping("getMenuData")
    public Response getMenuDataHandler() {
        LoginUser loginUser = getLoginUser();
        List<Menu> menuList = menuService.genMenuThreeByUserId(loginUser.getUser().getId(), MenuType.MENU);
        return Response.success(menuList);
    }

    @PreAuthorize("hasAuthority('system:user:list')")
    @ApiOperation(value = "查找用户列表")
    @PostMapping("pagination")
    public Response paginationHandler(@RequestBody DataGridRequest params) {
        params = addAccountConstraints(params);
        params.setSortOrder(SortOrder.DESC.getLabel());
        params.setSortName("createTime");
        params.getConditions().add(new Condition("isAdmin", Operator.NE.getLabel(), MyListUtils.genList("1")));
        IPage<User> userIPage = userService.paginate(params);
        IPage<UserVO> userVOIPage = User2UserVOConversion.pageConversion(userIPage);
        return Response.success(userVOIPage);
    }


    @ApiOperation(value = "获取角色")
    @PostMapping("getRoleSelectData")
    public Response getRoleSelectDataHandler() {
        List<Role> roleList = roleService.getByAccountId(getLoginUser().getUser().getAccountId());
        List<SelectVO> selectVOList = Bean2SelectConverter.converter(roleList, Role::getName, Role::getId);
        return Response.success(selectVOList);
    }

    @Log(busType = LogBusType.EDITANDSAVE, source = LogSourceType.MANAGE, module = LogModule.USERMANAGE)
    @ApiOperation(value = "保存user")
    @PreAuthorize("hasAuthority('system:user:save')")
    @PostMapping("save")
    public Response saveHandler(@RequestBody UserDTO userDTO) {
        userDTO.setIsAdmin(YesOrNo.NO.getValue());
        userService.saveHandler(getLoginUser().getUser(), userDTO);
        return Response.success();
    }

    @ApiOperation(value = "获取用户详情")
    @PreAuthorize("hasAuthority('system:user:save')")
    @PostMapping("loadMore")
    public Response loadMoreHandler(Long id) {
        UserVO userVO = userService.loadMoreHandler(id);
        return Response.success(userVO);
    }

    @Log(busType = LogBusType.ACTIVATION, source = LogSourceType.MANAGE, module = LogModule.USERMANAGE)
    @ApiOperation(value = "激活用户")
    @PreAuthorize("hasAuthority('system:user:active')")
    @PostMapping("active")
    public Response activeHandler(Long id) {
        userService.activeHandler(id);
        return Response.success();
    }

    @Log(busType = LogBusType.FREEZE, source = LogSourceType.MANAGE, module = LogModule.USERMANAGE)
    @ApiOperation(value = "冻结用户")
    @PreAuthorize("hasAuthority('system:user:freeze')")
    @PostMapping("freeze")
    public Response freezeHandler(Long id) {
        userService.freezeHandler(id);
        return Response.success();
    }

    @Log(busType = LogBusType.RESET_PASSWORD, source = LogSourceType.MANAGE, module = LogModule.USERMANAGE)
    @ApiOperation(value = "重置密码")
    @PreAuthorize("hasAuthority('system:user:resetPwd')")
    @PostMapping("resetPwd")
    public Response resetPwdHandler(Long id) {
        userService.resetPwdHandler(id);
        return Response.success();
    }

    @Log(busType = LogBusType.DELETE, source = LogSourceType.MANAGE, module = LogModule.USERMANAGE)
    @ApiOperation(value = "删除用户")
    @PreAuthorize("hasAuthority('system:user:delete')")
    @PostMapping("del")
    public Response delHandler(Long id) {
        userService.delHandler(id);
        return Response.success();
    }

    @Log(busType = LogBusType.EDIT_PASSWORD, source = LogSourceType.MANAGE, module = LogModule.USERMANAGE)
    @ApiOperation(value = "修改密码")
    @PostMapping("modifyPwd")
    public Response modifyPwdHandler(String oldPwd, String newPwd) {
        userService.modifyPwdHandler(getLoginUser().getUser().getId(), oldPwd, newPwd);
        return Response.success();
    }


    @PostMapping("getUserSelectData")
    public Response getUserSelectDataHandler() {
        List<SelectVO> selectVOList = userService.getUserSelectData(getLoginUser().getUser());
        return Response.success(selectVOList);
    }


}
